home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / GNU / GNUPLOTdoc.lha / docs / doc2ipf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-22  |  16.4 KB  |  541 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: doc2ipf.c,v 1.8 1995/05/09 15:36:33 drd Exp $";
  3. #endif
  4.  
  5. /*
  6.  * doc2ipf.c  -- program to convert Gnuplot .DOC format to OS/2
  7.  * ipfc  (.inf/.hlp) format.
  8.  *
  9.  * Modified by Roger Fearick from doc2rtf by M Castro 
  10.  *
  11.  * usage:  doc2ipf gnuplot.doc gnuplot.itl
  12.  *
  13.  */
  14.  
  15. /* note that tables must begin in at least the second column to */
  16. /* be formatted correctly and tabs are forbidden */
  17.  
  18. #include <stdio.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include <malloc.h>
  23.  
  24. #include "ansichek.h"
  25.  
  26. #define MAX_LINE_LEN    1024
  27. #define TRUE 1
  28. #define FALSE 0
  29.  
  30. int main __P(( int argc, char **argv ));
  31. void parse __P(( FILE *a ));
  32. int lookup __P(( char *s ));
  33. void refs __P(( int l, FILE *f ));
  34. void convert __P(( FILE *a, FILE *b ));
  35. void process_line __P(( char *line, FILE *b ));
  36.  
  37.  
  38. /* malloc's are not being checked ! */
  39.  
  40. void *xmalloc(size_t size)
  41. {
  42.     void *p=malloc(size);
  43.     if (p)
  44.         return p;
  45.     fprintf(stderr, "Malloc failed\n");
  46. }
  47.  
  48. struct LIST
  49. {
  50.     int level;
  51.     int line;
  52.     char *string;
  53.     struct LIST *next;
  54.     };
  55.  
  56. struct LIST *list = NULL;
  57. struct LIST *head = NULL;
  58.  
  59. struct LIST *keylist = NULL;
  60. struct LIST *keyhead = NULL;
  61.  
  62. struct TABENTRY { /* may have 3 column tables */
  63.         struct TABENTRY *next ;
  64.         char col[3][256] ;
  65.         } ;
  66.  
  67. struct TABENTRY table = {NULL} ;
  68. struct TABENTRY *tableins = &table ;
  69. int tablecols = 0 ;
  70. int tablewidth[3] = {0,0,0} ;        
  71. int tablelines = 0 ;
  72.  
  73. int debug = FALSE;
  74.  
  75. int main(argc,argv)
  76. int argc;
  77. char **argv;
  78. {
  79. FILE * infile;
  80. FILE * outfile;
  81.     if (argc==4 && argv[3][0]=='-' && argv[3][1]=='d')
  82.         debug = TRUE;
  83.  
  84.     if (argc != 3 && !debug) {
  85.         fprintf(stderr,"Usage: %s infile outfile\n", argv[0]);
  86.         return(1);
  87.     }
  88.     if ( (infile = fopen(argv[1],"r")) == (FILE *)NULL) {
  89.         fprintf(stderr,"%s: Can't open %s for reading\n",
  90.             argv[0], argv[1]);
  91.         return(1);
  92.     }
  93.     if ( (outfile = fopen(argv[2],"w")) == (FILE *)NULL) {
  94.         fprintf(stderr,"%s: Can't open %s for writing\n",
  95.             argv[0], argv[2]);
  96.     }
  97.     parse(infile);
  98.     convert(infile,outfile);
  99.     return(0);
  100. }
  101.  
  102. /* scan the file and build a list of line numbers where particular levels are */
  103. void parse(a)
  104. FILE *a;
  105. {
  106.     static char line[MAX_LINE_LEN];
  107.     char *c;
  108.     int lineno=0;
  109.     int lastline=0;
  110.  
  111.     while (fgets(line,MAX_LINE_LEN,a)) 
  112.     {
  113.     lineno++;
  114.     if (isdigit(line[0]))
  115.     {
  116.         if (list == NULL)    
  117.             head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
  118.         else
  119.             list = (list->next = (struct LIST *) xmalloc(sizeof(struct LIST)));
  120.         list->line = lastline = lineno;
  121.         list->level = line[0] - '0';
  122.         list->string = (char *) xmalloc (strlen(line)+1);
  123.         c = strtok(&(line[1]),"\n");
  124.         strcpy(list->string, c);
  125.         list->next = NULL;
  126.     }
  127.     if (line[0]=='?')
  128.     {
  129.         if (keylist == NULL)    
  130.             keyhead = (keylist = (struct LIST *) xmalloc(sizeof(struct LIST)));
  131.         else
  132.             keylist = (keylist->next = (struct LIST *) xmalloc(sizeof(struct LIST)));
  133.         keylist->line = lastline;
  134.         keylist->level = line[0] - '0';
  135.         c = strtok(&(line[1]),"\n");
  136.         if( c == NULL || *c == '\0' ) c = list->string ;
  137.         keylist->string = (char *) xmalloc (strlen(c)+1);
  138.         strcpy(keylist->string, c);
  139.         keylist->next = NULL;
  140.     }
  141.     }
  142.     rewind(a);
  143.     }
  144.  
  145. /* look up an in text reference */
  146. int
  147. lookup(s)
  148. char *s;
  149. {
  150.     char *c;
  151.     char tokstr[MAX_LINE_LEN];
  152.     char *match; 
  153.     int l;
  154.  
  155.     strcpy(tokstr, s);
  156.  
  157.     /* first try the ? keyword entries */
  158.     keylist = keyhead;
  159.     while (keylist != NULL)
  160.     {
  161.         c = keylist->string;
  162.         while (isspace(*c)) c++;
  163.         if (!strcmp(s, c)) return(keylist->line);
  164.         keylist = keylist->next;
  165.         }
  166.  
  167.     /* then try titles */
  168.     match = strtok(tokstr, " \n\t");
  169.     l = 0; /* level */
  170.     
  171.     list = head;
  172.     while (list != NULL)
  173.     {
  174.         c = list->string;
  175.         while (isspace(*c)) c++;
  176.         if (!strcmp(match, c)) 
  177.         {
  178.             l = list->level;
  179.             match = strtok(NULL, "\n\t ");
  180.             if (match == NULL)
  181.             {
  182.                 return(list->line);
  183.                 }
  184.             }
  185.         if (l > list->level)
  186.             break;
  187.         list = list->next;
  188.         }
  189.     return(-1);
  190.     }
  191.  
  192. /* search through the list to find any references */
  193. void
  194. refs(l, f)
  195. int l;
  196. FILE *f;
  197. {
  198.     int curlevel;
  199.     char str[MAX_LINE_LEN];
  200.     char *c;
  201.  
  202.     /* find current line */
  203.     list = head;
  204.     while (list->line != l)
  205.         list = list->next;
  206.     curlevel = list->level;
  207.     list = list->next;        /* look at next element before going on */
  208.     while (list != NULL)
  209.     {
  210.         /* we are onto the next topic so stop */
  211.         if (list->level == curlevel)
  212.             break;
  213.         /* these are the next topics down the list */
  214.         if (list->level == curlevel+1)
  215.         {
  216.             c = list->string;
  217.             }
  218.         list = list->next;
  219.         }
  220.     }
  221.  
  222. void
  223. convert(a,b)
  224.     FILE *a,*b;
  225. {
  226.     static char line[MAX_LINE_LEN];
  227.  
  228.     /* generate ipf header */
  229.     fprintf(b,":userdoc.\n:prolog.\n");
  230.     fprintf(b,":title.GNUPLOT\n");
  231.     fprintf(b,":docprof toc=1234.\n:eprolog.\n");
  232.  
  233.     /* process each line of the file */
  234.     while (fgets(line,MAX_LINE_LEN,a)) {
  235.        process_line(line, b);
  236.        }
  237.  
  238.     /* close final page and generate trailer */
  239.     fprintf(b,"\n:euserdoc.\n");
  240. }
  241.  
  242. void
  243. process_line(line, b)
  244.     char *line;
  245.     FILE *b;
  246. {
  247.     static int line_count = 0;
  248.     static char line2[MAX_LINE_LEN];
  249.     static int last_line;
  250.     char hyplink1[64] ;
  251.     char *pt, *tablerow ;
  252.     int i;
  253.     int j;
  254.     static int startpage = 1;
  255.     char str[MAX_LINE_LEN];
  256.     char topic[MAX_LINE_LEN];
  257.     int k, l;
  258.     static int tabl=0;
  259.     static int para=0;
  260.     static int inquote = FALSE;
  261.     static int inref = FALSE;
  262.     static int intable = FALSE ; 
  263.     static int intablebut = FALSE ;
  264.     static int introffheader = FALSE ;
  265.     static char tablechar = '@' ;
  266.     static FILE *bo= NULL, *bt = NULL ;
  267.     static char tabledelim[4]="%@\n" ;
  268.     static int nblanks = 0 ;
  269.  
  270.     line_count++;
  271.  
  272.     if( introffheader )
  273.         fprintf( stderr, "%s\n", line ) ; 
  274.     if( bo == NULL ) bo = b ;
  275.     i = 0;
  276.     j = 0;
  277.     nblanks = 0 ;
  278.     while( line[nblanks] == ' ' ) ++nblanks ;
  279.     while (line[i] != '\0')
  280.     {
  281.         if( introffheader ) {
  282.             if( line[i] != '\n' ) line2[j]=line[i] ;
  283.             else line2[j] = '\0' ;
  284.             }
  285.         else 
  286.         switch(line[i])
  287.         {
  288.             case '$':
  289.                 if( intable && line[0] == '%' ) {
  290.                    ++i ;
  291.                    if( line[i+1]=='$'|| line[i]=='x' || line[i]=='|'){
  292.                       while ( line[i] != '$' ) line2[j++]=line[i++] ;
  293.                       --j;
  294.                       }
  295.                    else {
  296.                        while( line[i] != '$' ) i++ ;
  297.                        if( line[i+1]==',' ) i++ ;
  298.                        if( line[i+1]==' ' ) i++ ;
  299.                        line2[j]=line[++i] ;
  300.                        }
  301.                    }
  302.                 else  line2[j] = line[i];
  303.                 break ;
  304.             case ':':
  305.                 strcpy( &line2[j], "&colon." ) ;
  306.                 j += strlen( "&colon." ) - 1 ;
  307.                 break ;
  308.  
  309.             case '&':
  310.                 strcpy( &line2[j], "&." ) ;
  311.                 j += strlen( "&." ) - 1 ;
  312.                 break ;
  313.                                 
  314.             case '\r':
  315.             case '\n':
  316.                 break;
  317.             case '`':    /* backquotes mean boldface or link */
  318.                 if( nblanks > 7 ) {
  319.                     line2[j]=line[i] ;
  320.                     break ;
  321.                     }
  322.                 if ((!inref) && (!inquote))
  323.                 {
  324.                     k=i+1;    /* index into current string */
  325.                     l=0;    /* index into topic string */
  326.                     while ((line[k] != '`') && (line[k] != NULL))
  327.                     {
  328.                         topic[l] = line[k];
  329.                         k++;
  330.                         l++;
  331.                         }
  332.                     topic[l] = NULL;
  333.                     k = lookup(topic);
  334.                     if (k > 0)
  335.                     {
  336.                         sprintf( hyplink1, ":link reftype=hd res=%d.", k ) ;
  337.                         strcpy( line2+j, hyplink1 ) ;
  338.                         j += strlen( hyplink1 )-1 ;
  339.                         
  340.                         inref = k;
  341.                         }
  342.                     else
  343.                     {
  344.                         if (debug)
  345.                             fprintf(stderr,"Can't make link for \042%s\042 on line %d\n",topic,line_count);
  346.                         strcpy( line2+j, ":hp2." ) ;
  347.                         j += 4 ;
  348.                         inquote = TRUE;
  349.                         }
  350.                     }
  351.                 else
  352.                 {
  353.                     if (inquote && inref)
  354.                         fprintf(stderr, "Warning: Reference Quote conflict line %d\n", line_count);
  355.                     if (inquote)
  356.                     {
  357.                         strcpy( line2+j, ":ehp2." ) ;
  358.                         j += 5 ;
  359.                         inquote = FALSE;
  360.                         }
  361.                     if (inref)
  362.                     {
  363.                         /* must be inref */
  364.                         strcpy( line2+j, ":elink." ) ;
  365.                         j += 6 ;
  366.                         inref = FALSE;
  367.                         }
  368.                 }
  369.                 break;
  370.             default:
  371.                 line2[j] = line[i];
  372.             }
  373.         i++;
  374.         j++;
  375.         line2[j] = '\0';
  376.         }
  377.  
  378.     i = 1;
  379.  
  380.     switch(line[0]) {        /* control character */
  381.        case '?': {            /* interactive help entry */
  382.                 if( intable ) intablebut = TRUE ;
  383.                 break;
  384.                 }
  385.        case '@': {            /* start/end table */
  386.                 intable = !intable ;  
  387.                 if( intable ) {
  388.                     tablechar = '@' ;
  389.                     introffheader = FALSE ;
  390.                     tablelines = 0;
  391.                     tablecols = 0 ;
  392.                     tableins = &table ;
  393.                     for(j=0;j<3;j++)tablewidth[j]=0 ;
  394.                     } 
  395.                 else { /* dump table */
  396.                     intablebut = FALSE ;
  397.                     tableins = table.next ;
  398.                     fprintf(b,":table cols=\'") ;
  399.                     for( j=0;j<3;j++)
  400.                         if(tablewidth[j]>0) fprintf(b," %d",tablewidth[j]);
  401.                     fprintf(b,"\'.\n") ;
  402.                     tableins=tableins->next ;     
  403.                     while( tableins != NULL ) {
  404.                         if( tableins->col[0][0] != '_' ) {
  405.                             fprintf(b,":row.\n" ) ;
  406.                             for( j=0;j<tablecols;j++) 
  407.                                 fprintf(b,":c.%s\n", tableins->col[j] ) ;
  408.                             }
  409.                         tableins = tableins->next ;
  410.                         }
  411.                     fprintf(b,":etable.\n") ;
  412.                     if( bt != NULL ) {
  413.                         rewind( bt ) ;
  414.                         while( fgets(str, MAX_LINE_LEN, bt) )
  415.                             fputs( str, b ) ; 
  416.                         fclose( bt ) ;
  417.                         remove( "doc2ipf.tmp" ) ;
  418.                         bt = NULL ;
  419.                         bo = b ;
  420.                         }
  421.                     }
  422.                 break;
  423.                 }
  424.        case '#': {            /* latex table entry */
  425.                 break;            /* ignore */
  426.                 }
  427.        case '%': {            /* troff table entry */
  428.                 if( intable ) {
  429.                     if( introffheader ) {
  430.                         fprintf( stderr, ">%s\n", line2 ) ; 
  431.                         fprintf( stderr, "tablechar: %c\n", tablechar ) ; 
  432.                         if( line2[1] == '.' ) break ;
  433.                         pt = strchr( line2, '(' ) ;
  434.                         if( pt != NULL ) tablechar = *(pt+1) ;
  435.                         fprintf( stderr, "tablechar: %c\n", tablechar ) ; 
  436.                         pt = strchr( line2+2, '.' ) ;
  437.                         if( pt != NULL ) introffheader = FALSE ;
  438.                         break ;
  439.                         }
  440.                     
  441.                     if( line[1] == '.' ) {  /* ignore troff commands */
  442.                         introffheader = TRUE ;
  443.                         break ;
  444.                         }
  445.                     tablerow = line2 ;
  446.                     tableins->next = xmalloc( sizeof( struct TABENTRY ) ) ;
  447.                     tableins = tableins->next ;
  448.                     tableins->next = NULL ;
  449.                     j=0 ;
  450.                     tabledelim[1] = tablechar ;
  451.                     while((pt=strtok( tablerow, tabledelim ))!=NULL) {
  452.                         if( *pt != '\0' ) { /* ignore null columns */
  453.                             strcpy( tableins->col[j], pt ) ;
  454.                             k=strlen( pt ) ;
  455.                             if( k > tablewidth[j] ) tablewidth[j]=k ;
  456.                             ++j ;
  457.                             tablerow = NULL ;
  458.                             if( j > tablecols ) tablecols = j ;
  459.                             }
  460.                         }
  461.                     for( j; j<3; j++ ) tableins->col[j][0]='\0' ;        
  462.                     }
  463.                 break;            /* ignore */
  464.                 }
  465.        case '\n':            /* empty text line */
  466.                 para = 0;
  467.                 tabl = 0;
  468.                 fprintf(bo,":p.");
  469.                 break;
  470.        case ' ': {            /* normal text line */
  471.                 if( intable && ! intablebut ) break ;
  472.                 if( intablebut ) { /* indexed items in  table, copy
  473.                                       to file after table by saving in
  474.                                       a temp file meantime */
  475.                     if( bt == NULL ) {
  476.                         fflush(bo) ;
  477.                         bt = fopen( "doc2ipf.tmp", "w+" ) ;
  478.                         if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  479.                         else bo = bt ; 
  480.                         }
  481.                     }
  482.                 if( intablebut && (bt==NULL )) break ;
  483.                 if ((line2[1] == NULL) || (line2[1] == '\n'))
  484.                     {
  485.                     fprintf(bo,":p."); 
  486.                     para = 0;
  487.                     }
  488.                 if (line2[1] == ' ') 
  489.                     {
  490.                     if (!tabl) fprintf(bo,":p.");                     
  491.                     fprintf(bo,"%s",&line2[1]); 
  492.                     fprintf(bo,"\n.br\n");
  493.                     tabl = 1;
  494.                     para = 0;
  495.                     }
  496.                 else
  497.                     {
  498.                     if (!para)
  499.                         {
  500.                         para = 1;        /* not in para so start one */
  501.                         tabl = 0;
  502.                         }
  503.                     fprintf(bo,"%s \n",&line2[1]); 
  504.                     }
  505.                 fflush(bo) ;
  506.                 break;
  507.                 }
  508.        case '^' : break; /* ignore */
  509.        default: {
  510.                 if (isdigit(line[0])) { /* start of section */
  511.                     if( intable ) {
  512.                         intablebut = TRUE ;
  513.                             if( bt == NULL ) {
  514.                                 fflush(bo) ;
  515.                                 bt = fopen( "doc2ipf.tmp", "w+" ) ;
  516.                                 if( bt==NULL ) fprintf(stderr, "cant open temp\n" ) ;
  517.                                 else bo = bt ; 
  518.                                 }
  519.                             }
  520.                         if (!startpage)
  521.                             refs(last_line,bo);
  522.                         para = 0;                    /* not in a paragraph */
  523.                         tabl = 0;
  524.                         last_line = line_count;
  525.                         startpage = 0;
  526.                         fprintf( stderr, "%d: %s\n", line_count, &line2[1] ) ;
  527.                         k=lookup(&line2[2]) ;
  528.                       /*if( k<0 ) fprintf(bo,":h%c.", line[0]=='1'?line[0]:line[0]-1);
  529.                         else*/ 
  530.                         fprintf(bo,":h%c res=%d.", line[0]=='1'?line[0]:line[0]-1,line_count);
  531.                         fprintf(bo,&(line2[1])); /* title */
  532.                         fprintf(bo,"\n:p." ) ;
  533.                         } 
  534.                     else
  535.                         fprintf(stderr, "unknown control code '%c' in column 1, line %d\n",
  536.                                 line[0], line_count);
  537.                     }
  538.                 break;
  539.                 }
  540.     }
  541.